<template>
<el-input v-model.trim="v" placeholder="验证码" maxlength="4">
  <template v-slot:suffix="">
    <span>
      <el-divider direction="vertical"></el-divider>
      <el-link :underline="false" :class="[$style.text]" class="mr-2" :disabled="sending" @click="onGetCode" v-if="countdown === 0">获取验证码</el-link>
      <el-link :underline="false" :class="[$style.text]" class="mr-2" disabled v-else>重新获取({{countdown}})</el-link>
    </span>
  </template>
</el-input>
</template>

<script lang="ts">
import { Component, Emit, Prop, Ref, Vue } from 'vue-property-decorator'

@Component
export default class CodeInput extends Vue {
  @Prop(String) value!: string

  @Prop() sendFn!: () => Promise<any>

  @Emit() input (value: string) {}

  timmingHandler: any = null

  countdown = 0

  sending = false

  localSendTime: number | null = null

  set v (value: string) {
    this.input(value)
  }

  get v (): string {
    return this.value
  }

  get sendTime () {
    return this.localSendTime || this.$storage.get('code-input-sendTime') as number
  }

  set sendTime (time: number) {
    this.localSendTime = time || null
    this.$storage.set('code-input-sendTime', time)
  }

  onGetCode () {
    if (!this.sendFn) throw new Error('sendFn undefined')
    this.sending = true
    this.sendFn().then(() => {
      this.triggerTimming()
    }).finally(() => {
      this.sending = false
    })
  }

  triggerTimming (reserved = false) {
    if (this.timmingHandler) clearInterval(this.timmingHandler)
    this.sendTime = reserved ? (this.sendTime || new Date(1971, 1, 1).getTime()) : Date.now()
    const handler = () => {
      const diff = Math.floor(((this.sendTime as number + 60 * 1000) - Date.now()) / 1000)
      this.countdown = diff > 0 ? diff : 0
      if (this.countdown === 0) clearInterval(this.timmingHandler)
    }
    handler()
    this.timmingHandler = setInterval(handler, 1000)
  }

  created () {
    this.triggerTimming(true)
  }

  beforeDestroy () {
    if (this.timmingHandler) clearInterval(this.timmingHandler)
  }
}
</script>
<style lang="scss" module>
@import "~@/styles/vars.scss";

.text {
  font-size: 12px;
  color: $text-secondary-color;
}
</style>
